package com.ushine.web.template.authority.facade.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ushine.web.base.model.system.OrgDO;
import com.ushine.web.base.model.system.PostDO;
import com.ushine.web.base.model.system.UserDO;
import com.ushine.web.base.service.IOrgService;
import com.ushine.web.base.service.IPostService;
import com.ushine.web.component.authority.config.DataFilterThreadLocal;
import com.ushine.web.component.authority.handler.InsertDataPermissionHandler;
import com.ushine.web.component.authority.handler.UpdateDataPermissionHandler;
import com.ushine.web.component.exception.ServiceException;
import com.ushine.web.template.authority.model.StaffDO;
import com.ushine.web.template.authority.view.StaffVO;
import com.ushine.web.template.authority.facade.IStaffFacade;
import com.ushine.web.template.authority.service.IStaffService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: yls
 * @Date: 2022/03/01 12:30
 * @Description:
 * @Version 1.0
 */
@Service
public class StaffFacadeImpl implements IStaffFacade {

    @Resource
    private IPostService postService;

    @Resource
    private IOrgService orgService;

    @Resource
    private IStaffService staffService;

    @Resource
    private InsertDataPermissionHandler insertDataPermissionHandler;

    @Resource
    private UpdateDataPermissionHandler updateDataPermissionHandler;

    /*********************************************数据权限测试-start***************************************************/
    @Override
    public List<StaffVO> listStaffByPermission() {
        List<StaffDO> staffList = staffService.listStaffs();
        Optional<List<StaffDO>> optionalStaff = Optional.ofNullable(staffList);
        if (optionalStaff.isPresent()) {
            /*
             * 查询对应的岗位信息
             */
            Set<Long> postIds = staffList.stream().map(StaffDO::getPostId).collect(Collectors.toSet());
            Map<Long, PostDO> postMap = new HashMap<>(10);
            if (!postIds.isEmpty()) {
                List<PostDO> postList = postService.listPosts(postIds);
                postList = Optional.ofNullable(postList).orElse(new ArrayList<>(0));
                postMap = postList.stream().collect(Collectors.toMap(PostDO::getId, post -> post));
            }
            /*
             * 查询对应的组织信息
             */
            Set<Long> orgIds = staffList.stream().map(StaffDO::getOrgId).collect(Collectors.toSet());
            Map<Long, OrgDO> orgMap = new HashMap<>(10);
            if (!orgIds.isEmpty()) {
                List<OrgDO> orgList = orgService.listOrgs(orgIds);
                orgList = Optional.ofNullable(orgList).orElse(new ArrayList<>(0));
                orgMap = orgList.stream().collect(Collectors.toMap(OrgDO::getId, org -> org));
            }
            /*
             * 组装 vo
             */
            List<StaffVO> staffVOList = new ArrayList<>();
            Map<Long, OrgDO> finalOrgMap = orgMap;
            Map<Long, PostDO> finalPostMap = postMap;
            staffList.forEach(staff -> {
                StaffVO staffVO = StaffVO.convertVO(staff, finalPostMap.get(staff.getPostId()), finalOrgMap.get(staff.getOrgId()));
                staffVOList.add(staffVO);
            });
            return staffVOList;
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<StaffVO> listStaffByPermissionThread(UserDO user) {
        DataFilterThreadLocal.setUser(user);
        List<StaffDO> staffList = staffService.listStaffs();
        Optional<List<StaffDO>> optionalStaff = Optional.ofNullable(staffList);
        if (optionalStaff.isPresent()) {
            /*
             * 查询对应的岗位信息
             */
            Set<Long> postIds = staffList.stream().map(StaffDO::getPostId).collect(Collectors.toSet());
            Map<Long, PostDO> postMap = new HashMap<>(10);
            if (!postIds.isEmpty()) {
                DataFilterThreadLocal.setUser(user);
                List<PostDO> postList = postService.listPosts(postIds);
                postList = Optional.ofNullable(postList).orElse(new ArrayList<>(0));
                postMap = postList.stream().collect(Collectors.toMap(PostDO::getId, post -> post));
            }
            /*
             * 查询对应的组织信息
             */
            Set<Long> orgIds = staffList.stream().map(StaffDO::getOrgId).collect(Collectors.toSet());
            Map<Long, OrgDO> orgMap = new HashMap<>(10);
            if (!orgIds.isEmpty()) {
                DataFilterThreadLocal.setUser(user);
                List<OrgDO> orgList = orgService.listOrgs(orgIds);
                orgList = Optional.ofNullable(orgList).orElse(new ArrayList<>(0));
                orgMap = orgList.stream().collect(Collectors.toMap(OrgDO::getId, org -> org));
            }
            /*
             * 组装 vo
             */
            List<StaffVO> staffVOList = new ArrayList<>();
            Map<Long, OrgDO> finalOrgMap = orgMap;
            Map<Long, PostDO> finalPostMap = postMap;
            staffList.forEach(staff -> {
                StaffVO staffVO = StaffVO.convertVO(staff, finalPostMap.get(staff.getPostId()), finalOrgMap.get(staff.getOrgId()));
                staffVOList.add(staffVO);
            });
            return staffVOList;
        }
        return new ArrayList<>(0);
    }

    /**
     * 功能描述:
     * 〈 添加员工，带数据权限 〉
     *
     * @param staff 员工信息实体
     * @return : java.lang.Boolean
     * @throws ServiceException 服务端自定义异常
     * @author : yls
     * @date : 2022/3/8 14:41
     */
    @Override
    public Boolean insertStaff(StaffDO staff) throws ServiceException {
        staff = insertDataPermissionHandler.getInsertDataObject(staff, "staff:user:insert");
        return staffService.insertStaff(staff);
    }

    /**
     * 功能描述:
     * 〈修改员工信息，带数据权限〉
     *
     * @param staff 员工信息实体
     * @return : java.lang.Boolean
     * @throws ServiceException 服务端自定义异常
     * @author : yls
     * @date : 2022/3/8 14:42
     */
    @Override
    public Boolean updateStaff(StaffDO staff) throws ServiceException {
        UpdateWrapper<StaffDO> updateDataWrapper = updateDataPermissionHandler.getUpdateDataWrapper(staff, "staff:user:update");
        // 如果权限过滤返回null，就表示该用户未设置列级权限，直接更新实体
        if (updateDataWrapper == null) {
            return staffService.updateStaff(staff);
        }
        return staffService.updateStaffByWrapper(updateDataWrapper);
    }

    /*********************************************数据权限测试-end***************************************************/

}
